package org.simp.core.message;



import org.apache.mina.core.buffer.IoBuffer;
import org.simp.common.Constants;
import org.simp.core.body.SimpBody;
import org.simp.core.head.Header;
import org.simp.core.head.SimpHeader;
import org.simp.exception.SimpIncompleteException;

/**
 * @author zhuhaitao at 2014-5-21
 *
 * 简单Im通信协议
 */
public  class SimpMessageWraper implements SimpMessage {

	/**头部长度**/
	private int headLength;
	/**消息头部**/
	SimpHeader head = new Header();
	
	SimpBody body;
	
	
	public SimpMessageWraper(){}
	
	public SimpMessageWraper(short mainId,short moudleId){
		head.setMainId(mainId);
		head.setMoudleId(moudleId);
	}
	
	
	public void setSrcAddress(String srcAddress){
		head.setSrcAddress(srcAddress);
	}
	public void setObjAddress(String objAddress){
		head.setObjAddress(objAddress);
	}
	public SimpMessageWraper(SimpBody body){
		this.body = body;
	}
	public SimpHeader getHead() {
		return head;
	}

	public void setHead(SimpHeader head) {
		this.head = head;
	}

	public SimpBody getBody() {
		return body;
	}

	public void setBody(SimpBody body) {
		this.body = body;
	}

	

	public byte[] encode() throws SimpIncompleteException {
		IoBuffer buffer = IoBuffer.allocate(256);
		buffer.setAutoExpand(true);
		byte[] bodyData = encodeBody();
		int contentLength = bodyData.length;
		head.setContentLength(contentLength);
		
		byte[] headData = encodeHead();
		headLength = headData.length;
		buffer.putInt(headLength);
		buffer.put(headData);
		buffer.put(bodyData);
		int length = buffer.position();
		buffer.rewind();
		byte [] data = new byte[length];
		buffer.get(data);
		return data;
	}

	public void decode(byte[] data) throws SimpIncompleteException {
		IoBuffer buffer  = IoBuffer.wrap(data);
		headLength = buffer.getInt();
		byte[] headData = new byte[headLength];
		buffer.get(headData);
		decodeHead(headData);
		int contentLength = head.getContentLength();
		
		byte[] bodyData = new byte[contentLength];
		buffer.get(bodyData);
		decodeBody(bodyData);
		
	}
	
	public  byte[] encodeBody(){
		if(body==null)
			return new byte[0];
		return body.encode();
	}
	
	public  void decodeBody(byte[] bodyData){
		if(body == null)
			return;
		body.decode(bodyData);
	}
	
	public void decodeHead(byte[] headData) throws SimpIncompleteException{
		head.decode(headData);
	}
	public byte[] encodeHead() throws SimpIncompleteException{
		return head.encode();
	}
	

	public boolean hasBody() {
		return body != null;
	}

	@Override
	public short getMainId() {
		return head.getMainId();
	}

	@Override
	public short getMoudleId() {
		return head.getMoudleId();
	}

	@Override
	public void addSrcAddress(String contexName) {
		String address = head.getSrcAddress();
		if(address == null){
			head.setSrcAddress(contexName);
		}else if(!address.contains(contexName)){
			address += Constants.ADDRESS_SPLIT +contexName;
			head.setSrcAddress(address);
		}
	}

	
	@Override
	public void decObjAddress(String contexName) {
		String address = head.getObjAddress();
		if(address.endsWith(contexName)){
			decObjAddress();
		}
		
	}

	@Override
	public void decObjAddress() {
		String address = head.getObjAddress();
		int index = address.lastIndexOf(Constants.ADDRESS_SPLIT);
		if(index >0){
			head.setObjAddress(address.substring(0,index));
		}
		
	}

	@Override
	public String getLastObjAddress() {
		String address = head.getObjAddress();
		if(address == null || "".equals(address)){
			return "";
		}
		String[] addresses = address.split(Constants.ADDRESS_SPLIT);
		return addresses[addresses.length -1];
	}
	
	public String toString(){
		return head.toString();
	}
}
